using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection.Emit;
using System.Text;
using RaisingStudio.SmallBasicCompiler.Completion;
using RaisingStudio.SmallBasicCompiler.Expressions;

namespace RaisingStudio.SmallBasicCompiler.Statements
{
    public class WhileStatement : Statement
    {
        public List<Statement> WhileBody = new List<Statement>();
        public Expression Condition;
        public TokenInfo WhileToken;
        public TokenInfo EndWhileToken;
        public override void AddSymbols(SymbolTable symbolTable)
        {
            if (this.Condition != null)
            {
                this.Condition.AddSymbols(symbolTable);
            }
            foreach (Statement current in this.WhileBody)
            {
                current.AddSymbols(symbolTable);
            }
        }
        public override void PrepareForEmit(CodeGenScope scope)
        {
            foreach (Statement current in this.WhileBody)
            {
                current.PrepareForEmit(scope);
            }
        }
        public override void EmitIL(CodeGenScope scope)
        {
            Label label = scope.ILGenerator.DefineLabel();
            Label label2 = scope.ILGenerator.DefineLabel();
            scope.ILGenerator.MarkLabel(label2);
            this.Condition.EmitIL(scope);
            scope.ILGenerator.EmitCall(OpCodes.Call, scope.TypeInfoBag.PrimitiveToBoolean, null);
            scope.ILGenerator.Emit(OpCodes.Brfalse, label);
            foreach (Statement current in this.WhileBody)
            {
                current.EmitIL(scope);
            }
            scope.ILGenerator.Emit(OpCodes.Br, label2);
            scope.ILGenerator.MarkLabel(label);
        }
        public override void PopulateCompletionItems(CompletionBag completionBag, int line, int column, bool globalScope)
        {
            if (base.StartToken.Line != line)
            {
                Statement statementContaining = Statement.GetStatementContaining(this.WhileBody, line);
                if (statementContaining != null)
                {
                    CompletionHelper.FillKeywords(completionBag, new Token[]
					{
						Token.EndWhile
					});
                    statementContaining.PopulateCompletionItems(completionBag, line, column, false);
                }
                return;
            }
            if (column <= this.WhileToken.EndColumn)
            {
                CompletionHelper.FillAllGlobalItems(completionBag, globalScope);
                return;
            }
            CompletionHelper.FillLogicalExpressionItems(completionBag);
        }
        public override int GetIndentationLevel(int line)
        {
            if (line == this.WhileToken.Line)
            {
                return 0;
            }
            if (this.EndWhileToken.Token != Token.Illegal && line == this.EndWhileToken.Line)
            {
                return 0;
            }
            Statement statementContaining = Statement.GetStatementContaining(this.WhileBody, line);
            if (statementContaining != null)
            {
                return 1 + statementContaining.GetIndentationLevel(line);
            }
            return 1;
        }
        public override string ToString()
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.AppendFormat(CultureInfo.CurrentUICulture, "{0} {1}", new object[]
			{
				this.WhileToken.Text, 
				this.Condition
			});
            stringBuilder.AppendLine();
            foreach (Statement current in this.WhileBody)
            {
                stringBuilder.AppendFormat(CultureInfo.CurrentUICulture, "  {0}", new object[]
				{
					current
				});
            }
            stringBuilder.AppendFormat(CultureInfo.CurrentUICulture, "{0}\r\n", new object[]
			{
				this.EndWhileToken.Text
			});
            return stringBuilder.ToString();
        }
    }
}
